package urjc.as.emergencies.resources;

import org.apache.log4j.Logger;
import org.restlet.Context;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.Representation;
import org.restlet.resource.ResourceException;
import org.restlet.resource.Variant;

import urjc.as.emergencies.client.CommToolkit;
import urjc.as.emergencies.data.PatientRecord;
import urjc.as.emergencies.data.AmbulanceList;
import urjc.as.emergencies.data.Mission;
import urjc.as.emergencies.data.MissionList;
import urjc.as.emergencies.data.PatientInfo;
import urjc.as.emergencies.data.Storage;

/**
 * Restlet para el recurso Lista Misiones
 * 
 * @author ahiges
 * 
 */
public class MissionsResource extends BaseResource {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(MissionsResource.class);

	/**
	 * Constructor por defecto.
	 */
	public MissionsResource(Context context, Request request, Response response) {
		super(context, request, response);

		// Variantes de representación soportadas
		getVariants().add(new Variant(MediaType.TEXT_XML));
	}

	/**
	 * Tratamiento del método POST. Este método es llamado por handlePost().
	 * Este método creará una misión en la lista de misiones.
	 */
	@Override
	public void acceptRepresentation(Representation entity)
			throws ResourceException {

		MissionList missionList = (MissionList) getStorage().getEntity(
				getRequest().getResourceRef().getBaseRef().toString());

		try {
			if (entity.getMediaType().equals(MediaType.TEXT_XML)) {
				// Inicializa la misión
				String xmlMission = getRequest().getEntity().getText();
				Mission mission = initializeMission(xmlMission, missionList);
				getResponse().setLocationRef(mission.getUri());
			} else {
				throw new ResourceException(
						Status.CLIENT_ERROR_UNSUPPORTED_MEDIA_TYPE);
			}

			// Si todo va bien, envía: (201 -- Created)
			getResponse().setStatus(Status.SUCCESS_CREATED);
		} catch (Exception e) {
			// Si saltan excepciones porque el destinatario no existe,
			// entonces:
			throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.restlet.resource.Resource#allowGet()
	 */
	@Override
	public boolean allowGet() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.restlet.resource.Resource#allowPost()
	 */
	@Override
	public boolean allowPost() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.restlet.resource.Resource#allowPut()
	 */
	@Override
	public boolean allowPut() {
		return true;
	}
	
	@Override
	public void storeRepresentation(Representation entity)
			throws ResourceException {
		
		try {
			if (entity.getMediaType().equals(MediaType.TEXT_XML)) {
				//Obtengo la nueva representacion
				String xmlMisiones = getRequest().getEntity().getText();
				MissionList nuevasMisiones = (MissionList) AmbulanceList.deserializar(xmlMisiones);
						
				// Almaceno
				Storage.getInstance().addEntity(nuevasMisiones);
				getResponse().setLocationRef(nuevasMisiones.getUri());
			} else {
				throw new ResourceException(
						Status.CLIENT_ERROR_UNSUPPORTED_MEDIA_TYPE);
			}

			// Si todo va bien, envía: (200(
			getResponse().setStatus(Status.SUCCESS_OK);
		} catch (Exception e) {
			// Si saltan excepciones porque el destinatario no existe,
			// entonces:
			throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
		}
	}
	

	private Mission initializeMission(String _xmlMission,
			MissionList missionList) {

		// 1 Desarializamos la missión
		Mission mission = (Mission) Mission.deserializar(_xmlMission);

		// 2) Le asignamos una URI al recurso y ponemos su estado interno
		int idMission = missionList.generateMissionID();
		mission.setUri(missionList.getUri() + "/" + idMission);
		logger.debug("Misión " + idMission + " creada en:" + mission.getUri());

		mission.setEstado(Mission.ESPERANDO_ASISTENCIA);
		mission.setIdMision(idMission);
		missionList.addMission(mission.getUri());

		// 2.1) Creamos el informe del paciente
		PatientInfo patientInfo = new PatientInfo();
		patientInfo.setUri(mission.getUri() + "/patientInfo");

		// 2.2) Creamos el historial
		PatientRecord hist = new PatientRecord();
		hist.setUri(patientInfo.getUri() + "/historial");

		// 2.3) Enlazamos los recursos
		mission.setPatientInformation(patientInfo.getUri());
		patientInfo.setHistorial(hist.getUri());

		// 3) Almacenamo la misión
		getStorage().addEntity(mission);

		// 4) Creamos los recursos información del paciente e historial
		createInfoPatient(patientInfo);
		createHistorical(hist);

		return mission;
	}

	/**
	 * Crea el historial del paciente a partir de una petición PUT sobre el
	 * recurso que previamente ya tiene asignado la URI
	 * 
	 * @param hist
	 */
	private Response createHistorical(PatientRecord hist) {
		return CommToolkit.doPut(hist);
	}

	/**
	 * Crea el info Patient a partir de un recurso que ya tiene previamente
	 * asignada la URI
	 * 
	 * @param patientInfo
	 */
	private Response createInfoPatient(PatientInfo patientInfo) {
		return CommToolkit.doPut(patientInfo);
	}



}
